package web.sso.http.process;

import org.springframework.core.MethodParameter;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.reactive.BindingContext;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * DATE: 2020/1/21
 * TIME: 5:59 下午
 *
 * @author：huangliming
 */
public abstract class HttpAnnotationProcess extends BaseProcess {

    /**
     * 获取注解中的value参数
     * @return
     */
    public abstract String getAnnotationParameterName(MethodParameter methodParameter);

    /**
     * 获取注解对应的参数map
     * @return
     */
    public abstract Mono<MultiValueMap<String, String>> getParameterMap(ServerWebExchange serverWebExchange);

    /**
     * 解析参数
     * @param methodParameter
     * @param bindingContext
     * @param serverWebExchange
     * @return
     */
    @Override
    public Mono<Object> resolveArgument(
            MethodParameter methodParameter,
            BindingContext bindingContext,
            ServerWebExchange serverWebExchange
    ) {
        return getParameterMap(serverWebExchange).flatMap(map -> {
                    String paramName = getAnnotationParameterName(methodParameter);
                    if (!StringUtils.hasText(paramName)) {
                        paramName = methodParameter.getParameterName();
                    }
                    String value = map.getFirst(paramName);
                    if (StringUtils.hasText(value)) {
                        Object v = super.convert(value, methodParameter);
                        return Mono.just(super.validate(v, methodParameter));
                    }

                    return super.resolveArgument(methodParameter, bindingContext, serverWebExchange);
                });
    }
}
